package com.dp.springsourcecodeanalysis.enums;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.dp.springsourcecodeanalysis.dto.EnumDTO;

/**
 * 枚举值基类
 *
 * @author shala
 */
public interface BaseEnum<C, M> {

    /**
     * 根据code返回枚举值
     *
     * @param enumClass
     *            枚举类
     * @param code
     *            code
     * @param <C>
     *            code
     * @param <T>
     *            text
     * @return Enum
     */
    static <C, T extends BaseEnum<C, ?>> T getByCode(Class<T> enumClass, C code) {
        T[] values = enumClass.getEnumConstants();
        for (T value : values) {
            if (value.getCode().equals(code)) {
                return value;
            }
        }
        return null;
    }

    /**
     * 枚举值code跟value组装成map
     *
     * @param enumClass
     *            枚举类
     * @param <C>
     *            code
     * @param <M>
     *            text
     * @param <T>
     *            enum
     * @return map,以
     */
    static <C, M, T extends BaseEnum<C, M>> Map<C, M> valuesToMap(Class<T> enumClass) {
        T[] values = enumClass.getEnumConstants();
        Map<C, M> map = new HashMap<>(values.length);
        for (T value : values) {
            map.put(value.getCode(), value.getText());
        }
        return map;
    }

    /**
     * 枚举值code跟value组装成map - 以 text 作为键值
     *
     * @param enumClass
     *            枚举类
     * @param <C>
     *            code
     * @param <M>
     *            text
     * @param <T>
     *            实体
     * @return 结果map
     */
    static <C, M, T extends BaseEnum<C, M>> Map<M, C> valuesToMapByText(Class<T> enumClass) {
        T[] values = enumClass.getEnumConstants();
        Map<M, C> map = new HashMap<>(values.length);
        for (T value : values) {
            map.put(value.getText(), value.getCode());
        }
        return map;
    }

    /**
     * 枚举值code跟value组装成DTO
     *
     * @param enumClass
     *            枚举类
     * @param <C>
     *            code
     * @param <M>
     *            text
     * @param <T>
     *            实体
     * @return 结果dto
     */
    static <C, M, T extends BaseEnum<C, M>> List<EnumDTO<C, M>> valuesToList(Class<T> enumClass) {
        T[] values = enumClass.getEnumConstants();
        List<EnumDTO<C, M>> list = new ArrayList<>(values.length);
        for (T value : values) {
            EnumDTO<C, M> enumDTO = new EnumDTO<>();
            enumDTO.setCode(value.getCode());
            enumDTO.setText(value.getText());
            list.add(enumDTO);
        }
        return list;
    }

    /**
     * 唯一编码
     *
     * @return 必须定一个可自定义类型的构造参数
     */
    C getCode();

    /**
     * 信息
     *
     * @return 非必须扩充的字段
     */
    default M getText() {
        return null;
    }
}
